using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
namespace BMC.ARSystem
{
	[Guid("1ebc3788-9bc6-4dd1-8837-823b467bcec9")]
	public class ARTypeMgr
	{
		private Hashtable _arTypeLookup;
		private Hashtable _arDataFiles;
		private static ARTypeMgr _theOnlyOne = new ARTypeMgr();
		public static ARTypeMgr Instance
		{
			get
			{
				return ARTypeMgr._theOnlyOne;
			}
		}
		public Hashtable Lookup
		{
			get
			{
				return this._arTypeLookup;
			}
		}
		public IDictionary ApplicationCommands
		{
			get
			{
				return (IDictionary)this._arDataFiles.get_Item("ApplicationCommands");
			}
		}
		public IDictionary Keywords
		{
			get
			{
				return (IDictionary)this._arDataFiles.get_Item("Keywords");
			}
		}
		public IDictionary DisplayProperties
		{
			get
			{
				return (IDictionary)this._arDataFiles.get_Item("DisplayProperties");
			}
		}
		private ARTypeMgr()
		{
			this._arTypeLookup = new Hashtable();
			try
			{
				this.LoadARTypeInfo(typeof(ARControlStruct));
			}
			catch (Exception var_0_23)
			{
			}
			this.LoadDataFiles();
		}
		internal static object toVariantGeneric(object given, Server server)
		{
			if (given is ICollection)
			{
				ICollection collection = given as ICollection;
				object[] array = new object[collection.get_Count()];
				int num = 0;
				IEnumerator enumerator = collection.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						object current = enumerator.get_Current();
						array[num++] = ARTypeMgr.Instance.toVariant(current, server);
					}
				}
				finally
				{
					IDisposable disposable = enumerator as IDisposable;
					if (disposable != null)
					{
						disposable.Dispose();
					}
				}
				return array;
			}
			Type type = given.GetType();
			MemberInfo[] array2 = type.FindMembers(8, 296, Type.FilterName, "ToVariant");
			if (array2 != null && array2.Length > 0)
			{
				return type.InvokeMember(array2[0].get_Name(), 296, null, null, new object[]
				{
					given,
					server
				});
			}
			return given;
		}
		internal static object ObjectFromVariantGeneric(ref object given, object var)
		{
			given = var;
			return given;
		}
		internal object toVariantAR(object given, Server server)
		{
			Type type = given.GetType();
			ARStructTypeInfo typeInfo = this.GetTypeInfo(type);
			object[] array = null;
			if (type.get_BaseType() == typeof(DictionaryBase))
			{
				string targetTypeStr = (string)typeInfo.MemberTypeStrings.get_Item(0);
				string targetTypeStr2 = (string)typeInfo.MemberTypeStrings.get_Item(1);
				IDictionary dictionary = given as IDictionary;
				array = new object[dictionary.get_Keys().get_Count()];
				int num = 0;
				IEnumerator enumerator = dictionary.get_Keys().GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						object current = enumerator.get_Current();
						object obj = new object[]
						{
							this.ObjectToVariant(targetTypeStr, current, server),
							this.ObjectToVariant(targetTypeStr2, dictionary.get_Item(current), server)
						};
						array[num++] = ((obj != null) ? this.toVariant(obj, server) : Missing.Value);
					}
					return array;
				}
				finally
				{
					IDisposable disposable = enumerator as IDisposable;
					if (disposable != null)
					{
						disposable.Dispose();
					}
				}
			}
			ARStructMemTypeInfo[] membersTypeInfo = typeInfo.MembersTypeInfo;
			array = new object[typeInfo.NumberOfMembers];
			ARStructMemTypeInfo[] array2 = membersTypeInfo;
			for (int i = 0; i < array2.Length; i++)
			{
				ARStructMemTypeInfo aRStructMemTypeInfo = array2[i];
				if (aRStructMemTypeInfo != null)
				{
					FieldInfo fieldInfo = aRStructMemTypeInfo.FieldInfo;
					object value = fieldInfo.GetValue(given);
					array[aRStructMemTypeInfo.Offset] = ((value != null) ? this.toVariant(value, server) : Missing.Value);
				}
			}
			return array;
		}
		internal object ObjectFromVariantAR(ref object given, object var, Server server)
		{
			if (var == null)
			{
				return given;
			}
			Type type = given.GetType();
			ARStructTypeInfo typeInfo = this.GetTypeInfo(type);
			if (typeInfo == null)
			{
				return given;
			}
			ARStructMemTypeInfo[] membersTypeInfo = typeInfo.MembersTypeInfo;
			object[] array = (object[])var;
			if (array == null || array.Length <= 0)
			{
				return given;
			}
			ARStructMemTypeInfo[] array2 = membersTypeInfo;
			for (int i = 0; i < array2.Length; i++)
			{
				ARStructMemTypeInfo aRStructMemTypeInfo = array2[i];
				if (aRStructMemTypeInfo != null)
				{
					FieldInfo fieldInfo = aRStructMemTypeInfo.FieldInfo;
					if (fieldInfo != null)
					{
						object obj = array[aRStructMemTypeInfo.Offset];
						if (fieldInfo.get_FieldType() == typeof(DateTime))
						{
							obj = Util.GetDateTime(Convert.ToUInt32(obj.ToString()));
						}
						else
						{
							if (fieldInfo.get_FieldType() == typeof(ArrayList))
							{
								string listMemberAttr = ARTypeMgr.GetListMemberAttr(fieldInfo);
								obj = this.ArrayListFromVariant(Type.GetType(listMemberAttr), (object[])obj, server);
							}
						}
						fieldInfo.SetValue(given, obj);
					}
				}
			}
			return given;
		}
		public object toVariant(object given)
		{
			return this.toVariant(given, null);
		}
		public object toVariant(object given, Server server)
		{
			if (given == null)
			{
				return Missing.Value;
			}
			Type type = given.GetType();
			if (this.GetTypeInfo(type) == null)
			{
				return ARTypeMgr.toVariantGeneric(given, server);
			}
			return this.toVariantAR(given, server);
		}
		public object ObjectToVariant(string targetTypeStr, object given, Server server)
		{
			if (targetTypeStr.Equals("System.Int32"))
			{
				return Convert.ToInt32(given);
			}
			if (targetTypeStr.Equals("System.String"))
			{
				return Convert.ToString(given);
			}
			if (targetTypeStr.Equals("ARValue") || targetTypeStr.Equals("ARPropValue"))
			{
				return Util.ConvertToARValue(given);
			}
			ARStructTypeInfo typeInfo;
			if (targetTypeStr != null)
			{
				typeInfo = this.GetTypeInfo(targetTypeStr);
			}
			else
			{
				typeInfo = this.GetTypeInfo(given.GetType());
			}
			if (typeInfo == null)
			{
				return ARTypeMgr.toVariantGeneric(given, server);
			}
			return this.toVariantAR(given, server);
		}
		public object ObjectFromVariant(Type typ, object var, Server server)
		{
			object obj = null;
			if (typ == typeof(string))
			{
				obj = "";
			}
			else
			{
				MemberInfo[] array = typ.FindMembers(8, 296, Type.FilterName, "createInstance");
				if (array != null && array.Length > 0)
				{
					return typ.InvokeMember(array[0].get_Name(), 296, null, null, new object[]
					{
						var,
						server
					});
				}
				obj = typ.InvokeMember(typ.get_Name(), 512, null, null, null);
			}
			return this.ObjectFromVariant(ref obj, var, server);
		}
		internal object ObjectFromVariant(ref object given, object var, Server server)
		{
			Type type = given.GetType();
			if (this.GetTypeInfo(type) == null)
			{
				return ARTypeMgr.ObjectFromVariantGeneric(ref given, var);
			}
			return this.ObjectFromVariantAR(ref given, var, server);
		}
		public Array ObjectArrayFromVariant(Type typ, object[] var, Server server)
		{
			int num = var.Length;
			Array array = Array.CreateInstance(typ, num);
			for (int i = 0; i < num; i++)
			{
				array.SetValue(this.ObjectFromVariant(typ, var[i], server), i);
			}
			return array;
		}
		public Array ObjectArrayFromVariant(string typStr, object[] var, Server server)
		{
			if (typStr.Equals("ARValue") || typStr.Equals("ARPropValue"))
			{
				int num = var.Length;
				Array array = Array.CreateInstance(typeof(object), num);
				for (int i = 0; i < num; i++)
				{
					array.SetValue(Util.ConvertFromARValue((object[])var[i], false, false), i);
				}
				return array;
			}
			return this.ObjectArrayFromVariant(Type.GetType(typStr), var, server);
		}
		public ArrayList ArrayListFromVariant(Type typ, object[] var, Server server)
		{
			if (var == null || var.Length == 0)
			{
				return new ArrayList();
			}
			Array array = (typ != null) ? this.ObjectArrayFromVariant(typ, var, server) : var;
			return new ArrayList(array);
		}
		public ArrayList ArrayListFromVariant(string typStr, object[] var, Server server)
		{
			Array array = (typStr != null) ? this.ObjectArrayFromVariant(typStr, var, server) : var;
			return new ArrayList(array);
		}
		public IDictionary BuildCustomDictionaryFromVariant(Type dictTyp, string ktypStr, int[] keyIndex, string vtypStr, int[] valIndex, object[] var, Server server)
		{
			IDictionary dictionary = (IDictionary)dictTyp.InvokeMember(dictTyp.get_Name(), 512, null, null, null);
			for (int i = 0; i < var.Length; i++)
			{
				object rawData = var[i];
				object at = Util.GetAt(rawData, keyIndex);
				object at2 = Util.GetAt(rawData, valIndex);
				object obj;
				if (ktypStr.Equals("System.Int32"))
				{
					obj = Convert.ToInt32(at);
				}
				else
				{
					if (ktypStr.Equals("System.String"))
					{
						obj = Convert.ToString(at);
					}
					else
					{
						obj = this.ObjectFromVariant(Type.GetType(ktypStr), at, server);
					}
				}
				object obj2;
				if (vtypStr.Equals("ARValue") || vtypStr.Equals("ARPropValue"))
				{
					obj2 = Util.ConvertFromARValue((object[])at2, Util.isStatusHistoryField(obj), false);
				}
				else
				{
					obj2 = this.ObjectFromVariant(Type.GetType(vtypStr), at2, server);
				}
				dictionary.set_Item(obj, obj2);
			}
			return dictionary;
		}
		public object BuildVariantFromCustomDictionary(string dictTypStr, string ktypStr, int[] keyIndex, string vtypStr, int[] valIndex, IDictionary dict)
		{
			return this.BuildVariantFromCustomDictionary(dictTypStr, ktypStr, keyIndex, vtypStr, valIndex, dict, null);
		}
		public object BuildVariantFromCustomDictionary(string dictTypStr, string ktypStr, int[] keyIndex, string vtypStr, int[] valIndex, IDictionary dict, Server server)
		{
			if (dict == null)
			{
				return null;
			}
			object[] array = new object[dict.get_Count()];
			ICollection keys = dict.get_Keys();
			int num = 0;
			ARStructTypeInfo typeInfo = this.GetTypeInfo(dictTypStr);
			IEnumerator enumerator;
			if (typeInfo == null)
			{
				enumerator = keys.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						object current = enumerator.get_Current();
						object[] array2 = new object[2];
						if (ktypStr.Equals("System.Int32"))
						{
							array2[0] = Convert.ToInt32(current);
						}
						else
						{
							if (ktypStr.Equals("System.String"))
							{
								array2[0] = Convert.ToString(current);
							}
							else
							{
								array2[0] = this.ObjectToVariant(ktypStr, current, server);
							}
						}
						if (vtypStr.Equals("ARValue") || vtypStr.Equals("ARPropValue"))
						{
							array2[1] = Util.ConvertToARValue(dict.get_Item(current));
						}
						else
						{
							array2[1] = this.ObjectToVariant(vtypStr, dict.get_Item(current), server);
						}
						array[num++] = array2;
					}
					return array;
				}
				finally
				{
					IDisposable disposable = enumerator as IDisposable;
					if (disposable != null)
					{
						disposable.Dispose();
					}
				}
			}
			string arg_118_0 = (string)typeInfo.MemberTypeStrings.get_Item(0);
			string arg_12A_0 = (string)typeInfo.MemberTypeStrings.get_Item(1);
			enumerator = keys.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					object current2 = enumerator.get_Current();
					object[] array3 = new object[2];
					if (ktypStr.Equals("System.Int32"))
					{
						array3[0] = Convert.ToInt32(current2);
					}
					else
					{
						if (ktypStr.Equals("System.String"))
						{
							array3[0] = Convert.ToString(current2);
						}
						else
						{
							array3[0] = this.ObjectToVariant(ktypStr, current2, server);
						}
					}
					if (vtypStr.Equals("ARValue") || vtypStr.Equals("ARPropValue"))
					{
						array3[1] = Util.ConvertToARValue(dict.get_Item(current2));
					}
					else
					{
						array3[1] = this.ObjectToVariant(vtypStr, dict.get_Item(current2), server);
					}
					array[num++] = array3;
				}
			}
			finally
			{
				IDisposable disposable = enumerator as IDisposable;
				if (disposable != null)
				{
					disposable.Dispose();
				}
			}
			return array;
		}
		public void LoadARTypeInfo(Type candidateType)
		{
			Hashtable arTypeLookup = this._arTypeLookup;
			Assembly assembly = Assembly.GetAssembly(candidateType);
			Type[] types = assembly.GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				Type type = types[i];
				ARStructTypeInfo aRStructTypeInfo = ARTypeMgr.LoadARStructTypeInfo(type);
				if (aRStructTypeInfo != null)
				{
					arTypeLookup.set_Item(type, aRStructTypeInfo);
				}
			}
			arTypeLookup.set_Item("ARValue", new ARStructTypeInfo(null, "ARValueStruct", 2, null, "System.Int32|System.Object"));
			arTypeLookup.set_Item("ARPropValue", new ARStructTypeInfo(null, "ARValueStruct", 2, null, "System.Int32|System.Object"));
			arTypeLookup.set_Item("ARDisplayInstanceList", new ARStructTypeInfo(null, "ARDisplayInstanceList", 2, null, "System.Int32|BMC.ARSystem.DisplayInstance"));
		}
		internal static ARStructTypeInfo LoadARStructTypeInfo(Type typ)
		{
			object[] customAttributes = typ.GetCustomAttributes(typeof(ARStructTypeInfoAttribute), true);
			if (customAttributes == null || customAttributes.Length <= 0)
			{
				return null;
			}
			string text = null;
			int num = 0;
			string memTypStrs = null;
			object[] array = customAttributes;
			int i = 0;
			if (i < array.Length)
			{
				ARStructTypeInfoAttribute aRStructTypeInfoAttribute = (ARStructTypeInfoAttribute)array[i];
				text = aRStructTypeInfoAttribute.Name;
				num = (int)aRStructTypeInfoAttribute.NumberOfMembers;
				memTypStrs = aRStructTypeInfoAttribute.MembersTypeString;
			}
			if (text == null)
			{
				return null;
			}
			FieldInfo[] fields = typ.GetFields(52);
			new object[fields.Length];
			ARStructMemTypeInfo[] array2 = new ARStructMemTypeInfo[num];
			FieldInfo[] array3 = fields;
			for (i = 0; i < array3.Length; i++)
			{
				FieldInfo fieldInfo = array3[i];
				object[] customAttributes2 = fieldInfo.GetCustomAttributes(typeof(ARStructMemTypeInfoAttribute), true);
				if (customAttributes2 != null && customAttributes2.Length > 0)
				{
					string name = ((ARStructMemTypeInfoAttribute)customAttributes2[0]).Name;
					uint offset = ((ARStructMemTypeInfoAttribute)customAttributes2[0]).Offset;
					bool isList = ((ARStructMemTypeInfoAttribute)customAttributes2[0]).IsList;
					ARStructMemTypeInfo aRStructMemTypeInfo = new ARStructMemTypeInfo(fieldInfo, name, (int)offset, isList);
					array2[(int)offset] = aRStructMemTypeInfo;
				}
			}
			return new ARStructTypeInfo(typ, text, num, array2, memTypStrs);
		}
		public ARStructTypeInfo GetTypeInfo(Type typ)
		{
			return (ARStructTypeInfo)this._arTypeLookup.get_Item(typ);
		}
		public ARStructTypeInfo GetTypeInfo(string typStr)
		{
			Type type = Type.GetType(typStr);
			if (type != null)
			{
				return this.GetTypeInfo(type);
			}
			return (ARStructTypeInfo)this._arTypeLookup.get_Item(typStr);
		}
		public static string GetListMemberAttr(FieldInfo fi)
		{
			object[] customAttributes = fi.GetCustomAttributes(typeof(ARStructMemTypeInfoAttribute), true);
			if (customAttributes == null || customAttributes.Length <= 0)
			{
				return "System.Object";
			}
			object[] array = customAttributes;
			for (int i = 0; i < array.Length; i++)
			{
				ARStructMemTypeInfoAttribute aRStructMemTypeInfoAttribute = (ARStructMemTypeInfoAttribute)array[i];
				if (aRStructMemTypeInfoAttribute.IsList)
				{
					return aRStructMemTypeInfoAttribute.MemberType;
				}
			}
			return "System.Object";
		}
		public string ObjectToString(object o, int indent)
		{
			return this.ObjectToString(o, indent, false);
		}
		public string ObjectToString(object o, int indent, bool skipNumItemsHeader)
		{
			return this.ObjectToString(o, indent, Environment.get_NewLine(), Environment.get_NewLine(), skipNumItemsHeader, null);
		}
		public string ObjectToString(object o, int indent, string countDelim, string elemDelim, bool skipNumItemsHeader, Server server)
		{
			StringBuilder stringBuilder = new StringBuilder();
			if (o == null)
			{
				stringBuilder.AppendFormat("{0}(null)", new string(' ', indent));
			}
			else
			{
				if (o is ICollection)
				{
					ICollection collection = o as ICollection;
					if (!skipNumItemsHeader)
					{
						stringBuilder.AppendFormat("{0}[{1} items]{2}", new string(' ', indent), collection.get_Count(), countDelim);
					}
					IEnumerator enumerator = collection.GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							object current = enumerator.get_Current();
							stringBuilder.AppendFormat("{0}{1}", this.ObjectToString(current, indent + 2, countDelim, elemDelim, skipNumItemsHeader, server), elemDelim);
						}
						goto IL_105;
					}
					finally
					{
						IDisposable disposable = enumerator as IDisposable;
						if (disposable != null)
						{
							disposable.Dispose();
						}
					}
				}
				Type type = o.GetType();
				if (this.GetTypeInfo(type) == null || type.GetMethod("ToString", 22) != null)
				{
					stringBuilder.AppendFormat("{0}{1}", new string(' ', indent), o.ToString());
				}
				else
				{
					object o2 = this.toVariantAR(o, server);
					stringBuilder.Append(this.ObjectToString(o2, indent + 2, countDelim, elemDelim, skipNumItemsHeader, server));
				}
			}
			IL_105:
			return stringBuilder.ToString();
		}
		public static void Print(object o, int indent)
		{
			if (o is ICollection)
			{
				ICollection collection = o as ICollection;
				ARTypeMgr.Print(string.Format("[{0} items]", collection.get_Count()), indent);
				IEnumerator enumerator = collection.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						object current = enumerator.get_Current();
						ARTypeMgr.Print(current, indent + 2);
					}
					return;
				}
				finally
				{
					IDisposable disposable = enumerator as IDisposable;
					if (disposable != null)
					{
						disposable.Dispose();
					}
				}
			}
			if (o is DictionaryEntry)
			{
				DictionaryEntry dictionaryEntry = (DictionaryEntry)o;
				ARTypeMgr.Print(dictionaryEntry.get_Key(), indent + 2);
				dictionaryEntry = (DictionaryEntry)o;
				ARTypeMgr.Print(dictionaryEntry.get_Value(), indent + 2);
				return;
			}
			if (o is DateTime)
			{
				string arg_DE_0 = "{0}{1}";
				object arg_DE_1 = new string(' ', indent);
				object arg_DE_2;
				if (o != null)
				{
					DateTime dateTime = (DateTime)o;
					arg_DE_2 = dateTime.ToLocalTime().ToString();
				}
				else
				{
					arg_DE_2 = "(null)";
				}
				Console.WriteLine(arg_DE_0, arg_DE_1, arg_DE_2);
				return;
			}
			Console.WriteLine("{0}{1}", new string(' ', indent), (o == null) ? "(null)" : o.ToString());
		}
		private void LoadDataFiles()
		{
			this._arDataFiles = new Hashtable();
			this._arDataFiles.set_Item("ApplicationCommands", new DictionaryDataLoader("BMC.ARSystem.Data.ApplicationCommands.data").Data);
			this._arDataFiles.set_Item("Keywords", new DictionaryDataLoader("BMC.ARSystem.Data.Keywords.data").Data);
			this._arDataFiles.set_Item("DisplayProperties", new DictionaryDataLoader("BMC.ARSystem.Data.DisplayProperties.data").Data);
		}
	}
}
